package com.kqb.sgcommon.file.oss.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.kqb.sgcommon.base.exception.BusinessException;
import com.kqb.sgcommon.base.response.FileUploadResult;
import com.kqb.sgcommon.file.config.properties.OSSProperties;
import com.kqb.sgcommon.file.oss.FileService;
import com.kqb.sgcommon.file.utils.FileUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 杉果树皮
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Resource
    private OSS ossClient;
    @Resource
    private OSSProperties ossProperties;

    @Override
    public boolean upload(String path, InputStream inputStream) {

        boolean result = false;
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(ossProperties.getBucketName(), path, inputStream);
            PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
            if (StrUtil.isNotBlank(putObjectResult.getRequestId())) {
                result = true;
                log.info("文件上传成功，路径: {}, 请求ID: {}", path, putObjectResult.getRequestId());
            }
        } catch (OSSException oe) {
            log.error("OSS服务异常: ErrorMessage: {}, ErrorCode: {}, RequestId: {}, HostId: {}",
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
        } catch (ClientException e) {
            log.error("OSS客户端异常: {}", e.getMessage());
        }
        return result;
    }

    @Override
    public InputStream download(String path) {
        //判断文件是否存在

        try {
            boolean exist = ossClient.doesObjectExist(ossProperties.getBucketName(), path);
            if (!exist) {
                log.info("OSS文件不存在: {}", path);
                return null;
            }
            OSSObject ossObject = ossClient.getObject(ossProperties.getBucketName(), path);
            InputStream objectContent = ossObject.getObjectContent();

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] readBuffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = objectContent.read(readBuffer)) != -1) {
                outputStream.write(readBuffer, 0, bytesRead);
            }

            objectContent.close();

            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (OSSException oe) {
            log.error("OSS服务异常: ErrorMessage: {}, ErrorCode: {}, RequestId: {}, HostId: {}",
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
        } catch (IOException e) {
            log.error("文件下载失败: {}", e.getMessage());
        }

        throw new RuntimeException("文件下载失败");
    }

    @Override
    public boolean delete(String path) {
        try {
            boolean exist = ossClient.doesObjectExist(ossProperties.getBucketName(), path);
            if (!exist) {
                log.info("OSS文件不存在: {}", path);
                return false;
            }
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(ossProperties.getBucketName(), path);
            log.info("删除文件成功: {}", path);
            return true;
        } catch (OSSException oe) {
            log.error("OSS服务异常: ErrorMessage: {}, ErrorCode: {}, RequestId: {}, HostId: {}",
                    oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
        }
        return true;
    }

    @Override
    public FileUploadResult uploadImage(String module, MultipartFile file) {
        //校验文件
        if (file == null) {
            throw new BusinessException("上传文件不存在");
        }
        if (FileUtils.isImage(file)) {
            throw new BusinessException("上传文件格式错误,只支持图片");
        }
        //获取原始文件信息（原始名称，文件类型）

        try {
            String ossPath = FileUtils.generateOssPath(module, file);
            String name = FileUtils.generateName(file);
            String path = ossPath + "/" + name;
            boolean upload = upload(path, file.getInputStream());
            if (!upload) {
                log.error("文件上传失败: {}", path);
                return null;
            }
            return FileUploadResult.builder()
                    .currentName(name)
                    .originalName(FileUtils.getFileName(file))
                    .path(path)
                    .fileSize(FileUtils.getFileSizeInKb(file))
                    .fileType(FileUtils.getFileExtension(file))
                    .build();
        } catch (IOException e) {
            log.error("图片上传异常: {}", e.getMessage(), e);
            return null;
        }

    }

    @Override
    public List<FileUploadResult> batchUploadImages(String module, List<MultipartFile> files) {
        if (CollUtil.isEmpty(files)) {
            log.error("批量上传的文件列表为空");
            return new ArrayList<>();
        }

        return files.stream().
                map(file -> uploadImage(module, file))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

    }

    @Override
    public String externalPath(String path) {
        return ossProperties.getBucketDomain() + "/" + path;
    }


}
